package com.tjhzzx.hnceCore2024.command;

import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import com.tjhzzx.hnceCore2024.history.HistoryManager;
import com.tjhzzx.hnceCore2024.history.entities.HistoryDataItem;
import com.tjhzzx.hnceCore2024.history.entities.HistoryDataMessage;
import com.tjhzzx.hnceCore2024.history.entities.HistoryDataUnit;
import com.tjhzzx.hnceCore2024.servlet.AbstractServletCommand;
import com.tjhzzx.hnceCore2024.servlet.JSONResult;
import com.tjhzzx.hnceCore2024.util.EnergyUtil;
import com.tjhzzx.hnceCore2024.util.ExcelUtil;
import com.tjhzzx.hnceCore2024.util.TlsUtil;
import com.tridium.json.JSONArray;
import com.tridium.json.JSONObject;
import org.apache.commons.lang3.StringUtils;

import javax.baja.web.WebOp;
import java.util.*;
import java.util.logging.Logger;

public class EnergySearchCommand extends AbstractServletCommand {
    private static final Logger LOGGER = Logger.getLogger(EnergySearchCommand.class.getName());

    private static List<Map<String, Object>> buildTDatas(List<String> names, List<List<HistoryDataUnit>> lists, SortedSet<String> xDatas, boolean bValue) {
        List<Map<String, Object>> tDatas = new ArrayList<>();
        String[] xDatasNew = new String[xDatas.size()];
        xDatas.toArray(xDatasNew);
        List<String[]> newLists = new ArrayList<>();
        for(List<HistoryDataUnit> list : lists) {
            String[] newList = new String[xDatasNew.length];
            Arrays.fill(newList, "-");
            for(HistoryDataUnit data: list) {
                int idx = 0;
                for(int i=0; i<xDatasNew.length; i++) {
                    if(data.time.equals(xDatasNew[i])) {
                        idx = i;
                        break;
                    }
                }
                newList[idx] = data.value;
            }
            newLists.add(newList);
        }
        for(int i=0; i<xDatasNew.length; i++) {
            Map<String, Object> item = new LinkedHashMap<>();
            item.put("id", i+1);
            item.put("time", xDatasNew[i]);
            double sum = 0;
            for(int j=0;j<names.size();j++) {
                String value = (newLists.get(j))[i];
                if(!"-".equals(value)) {
                    sum += Double.parseDouble(value);
                }
                item.put(names.get(j), value);
            }
            if(!bValue) {
                for(String key:item.keySet()) {
                    if(names.contains(key)) {
                        String value = (String) item.get(key);
                        if(!"-".equals(value)) {
                            item.put(key, Double.parseDouble(value)/sum);
                        }
                    }
                }
            }
            tDatas.add(item);
        }
        return tDatas;
    }

    /**
     * @description:  计算费用
     * @param:
     * @return:
     * @date: 2022/9/23
     */
    private static List<HistoryDataUnit> computePrice(List<HistoryDataUnit> units, int peroid, JSONArray price) {
        List<HistoryDataUnit> unitList = new ArrayList<>();
        if(0 == peroid) {
            double sum = 0, prev = 0;
            String month = "";
            for(HistoryDataUnit unit : units) {
                double cost = 0;
                String[] dates = unit.getTime().trim().split("-");
                if(!month.equals(dates[0]+"-"+dates[1])) {
                    sum = 0;
                    prev = 0;
                    month = dates[0]+"-"+dates[1];
                }
                double value = Double.parseDouble(unit.getValue());
                sum += value;
                for(int i=0; i<price.length(); i++) {
                    JSONObject item = price.getJSONObject(i);
                    if(1 == item.getInt("c") || sum < item.getDouble("e")) {
                        cost += (sum-item.getDouble("s")) * item.getDouble("p");
                        break;
                    } else {
                        cost += (item.getDouble("e") - item.getDouble("s")) * item.getDouble("p");
                    }
                }
                cost -= prev;
                prev += cost;
                HistoryDataUnit historyDataUnit = new HistoryDataUnit();
                historyDataUnit.setTime(unit.getTime());
                historyDataUnit.setValue(String.format("%.2f", cost));
                unitList.add(historyDataUnit);
            }
        } else {
            for(HistoryDataUnit unit : units) {
                double cost = 0;
                double value = Double.parseDouble(unit.getValue());
                for(int i=0; i<price.length(); i++) {
                    JSONObject item = price.getJSONObject(i);
                    if(1 == item.getInt("c") || value < item.getDouble("e")) {
                        cost += (value-item.getDouble("s")) * item.getDouble("p");
                        break;
                    } else {
                        cost += (item.getDouble("e") - item.getDouble("s")) * item.getDouble("p");
                    }
                }
                HistoryDataUnit historyDataUnit = new HistoryDataUnit();
                historyDataUnit.setTime(unit.getTime());
                historyDataUnit.setValue(String.format("%.2f", cost));
                unitList.add(historyDataUnit);
            }
            if(2 == peroid) {
                Map<String, Double> map = new HashMap<>();
                for(HistoryDataUnit unit : unitList) {
                    String[] dates = unit.getTime().trim().split("-");
                    if(!map.containsKey(dates[0])) {
                        map.put(dates[0], 0.0);
                    }
                    double sum = map.get(dates[0]);
                    sum += Double.parseDouble(unit.getValue());
                    map.put(dates[0], sum);
                }
                unitList = new ArrayList<>();
                for(String key : map.keySet()) {
                    HistoryDataUnit unit = new HistoryDataUnit();
                    unit.setTime(key);
                    unit.setValue(String.format("%.2f", map.get(key)));
                    unitList.add(unit);
                }
            }
        }
        return unitList;
    }

    public void postExportEnergyUnits(WebOp op, String queryString) throws Exception {
        Map<String, Object> params = resolveParams(queryString);
        String historyIds = (String) params.get("h");
        String price = (String) params.get("price");
        int peroid = Integer.parseInt((String) params.get("p"));
        if(StringUtils.isBlank(historyIds)) {
            return;
        }
        JSONArray priceArr = null;
        if(StringUtils.isNotBlank(price)) {
            priceArr = new JSONArray(price);
        }
        String[] historyIdArray = historyIds.split("\\|\\|\\|");
        SortedSet<String> xDatas = new TreeSet<>();
        List<List<HistoryDataUnit>> lists = new ArrayList<>();
        List<String> names = new ArrayList<>();
        for(String historyId : historyIdArray) {
            String[] history = historyId.split("\\|\\|");
            HistoryDataItem historyDataItem = new HistoryDataItem();
            historyDataItem.name = history[0];
            names.add(history[0]);
            historyDataItem.ord  = history[1].replace("history:", "");
            List<HistoryDataItem> items = new ArrayList<>();
            items.add(historyDataItem);
            HistoryDataMessage request = new HistoryDataMessage();
            request.startTime = (String) params.get("startTime");
            request.endTime = (String) params.get("endTime");
            String[] timeRange = EnergyUtil.getStatisticsTimeRange(request.startTime, request.endTime, peroid, 2, priceArr.length()>0);
            if(null == timeRange || timeRange.length < 2) {
                return;
            }
            request.startTime = timeRange[0];
            request.endTime = timeRange[1];
            request.items = items;
            Map<String, Object> startMap = new LinkedHashMap<>();
            HistoryDataMessage result = HistoryManager.searchHistoryData(request);
            if(result != null && result.items != null && result.items.size()>0
                    && result.items.get(0).units != null
                    && result.items.get(0).units.size()>0) {
                List<HistoryDataUnit> units = result.items.get(0).units;
                List<JSONObject> list = new ArrayList<>();
                for (int i = 0; i < units.size(); i++) {
                    HistoryDataUnit unit = units.get(i);
                    Date date = TlsUtil.string2utilDate(unit.time);
                    String time = TlsUtil.utilDate2String(date, "yyyy-MM-dd", false);
                    if(peroid == 1 || (peroid == 2 && priceArr.length()>0)) {
                        time = TlsUtil.utilDate2String(date, "yyyy-MM", false);
                    } else if(peroid == 2 && priceArr.length()==0){
                        time = TlsUtil.utilDate2String(date, "yyyy", false);
                    }
                    if(!startMap.containsKey(time)) {
                        startMap.put(time, unit.value);
                    }
                    if(i == units.size()-1) {
                        startMap.put("end", unit.value);
                    }
                }
                String prev = null;
                units = new ArrayList<>();
                for(String time: startMap.keySet()) {
                    if(null == prev) {
                        prev = time;
                        continue;
                    }
                    double value = Double.parseDouble((String) startMap.get(time))-Double.parseDouble((String) startMap.get(prev));
                    HistoryDataUnit unit = new HistoryDataUnit();
                    unit.setTime(prev);
                    unit.setValue(String.valueOf(value));
                    units.add(unit);
                    prev = time;
                }
                List<HistoryDataUnit> unitList = new ArrayList<>();
                if(priceArr.length() > 0) {
                    units = computePrice(units, peroid, priceArr);
                    if(0 == peroid) {
                        Date startTime = TlsUtil.string2utilDate((String) params.get("startTime"), "yyyy-MM-dd");
                        for(HistoryDataUnit unit : units) {
                            Date date = TlsUtil.string2utilDate(unit.getTime(), "yyyy-MM-dd");
                            if(date.after(startTime) || date.equals(startTime)) {
                                unitList.add(unit);
                            }
                        }
                        units = unitList;
                    }
                }
                unitList = new ArrayList<>();
                for(HistoryDataUnit unit : units) {
                    xDatas.add(unit.getTime());
                    unit.setValue(String.format("%.2f", Double.parseDouble(unit.getValue())));
                    unitList.add(unit);
                }
                lists.add(unitList);
            }
        }
        List<ExcelExportEntity> headers = new ArrayList<>();
        headers.add(new ExcelExportEntity("ID", "id"));
        headers.add(new ExcelExportEntity("采集时间", "time"));
        for(String name: names) {
            headers.add(new ExcelExportEntity(name, name));
        }
        List<Map<String, Object>> tDatas = buildTDatas(names, lists, xDatas, true);
        String path = TlsUtil.buildStationHomeAbsolutePath("file:^history/export");
        String fileName = "result-" + TlsUtil.utilDate2String(new Date(),"yyyy-MM-dd-HH-mm-ss", false) + ".xls";
        ExcelUtil.exportExcel(tDatas, headers, path, fileName, op.getResponse());
    }

    public void postEnergyUnits(WebOp op, String queryString) throws Exception {
        JSONResult pageResult = new JSONResult();
        Map<String, Object> params = resolveParams(queryString);
        String historyIds = (String) params.get("h");
        int bTDatas = Integer.parseInt((String) params.get("t"));
        int peroid = Integer.parseInt((String) params.get("p"));
        String price = (String) params.get("price");
        if(StringUtils.isBlank(historyIds)) {
            jsonResponse(JSONResult.error("历史查询参数'historyId'配置错误"));
            return;
        }
        JSONArray priceArr = null;
        if(StringUtils.isNotBlank(price)) {
            priceArr = new JSONArray(price);
        }
        List<JSONObject> datas = new ArrayList<>();
        SortedSet<String> xDatas = new TreeSet<>();
        List<String> names = new ArrayList<>();
        List<List<HistoryDataUnit>> lists = new ArrayList<>();
        String[] historyIdArray = historyIds.split("\\|\\|\\|");
        for(String historyId : historyIdArray) {
            String[] history = historyId.split("\\|\\|");
            HistoryDataItem historyDataItem = new HistoryDataItem();
            historyDataItem.name = history[0];
            names.add(history[0]);
            historyDataItem.ord  = history[1].replace("history:", "");
            List<HistoryDataItem> items = new ArrayList<>();
            items.add(historyDataItem);
            HistoryDataMessage request = new HistoryDataMessage();
            request.startTime = (String) params.get("startTime");
            request.endTime = (String) params.get("endTime");
            // 时间范围正确：与能耗、费用无关
            String[] timeRange = EnergyUtil.getStatisticsTimeRange(request.startTime, request.endTime, peroid, 2, priceArr.length()>0);
            if(null == timeRange || timeRange.length < 2) {
                jsonResponse(JSONResult.error("历史查询时间范围错误"));
                return;
            }
            request.startTime = timeRange[0];
            request.endTime = timeRange[1];
            request.items = items;
            Map<String, Object> startMap = new LinkedHashMap<>();
            HistoryDataMessage result = HistoryManager.searchHistoryData(request);
            if(result != null && result.items != null && result.items.size()>0 && result.items.get(0).units != null && result.items.get(0).units.size()>0) {
                List<HistoryDataUnit> units = result.items.get(0).units;
                List<JSONObject> list = new ArrayList<>();
                for (int i = 0; i < units.size(); i++) {
                    HistoryDataUnit unit = units.get(i);
                    Date date = TlsUtil.string2utilDate(unit.time);
                    String time = TlsUtil.utilDate2String(date, "yyyy-MM-dd", false);
                    if(peroid == 1 || (peroid == 2 && priceArr.length()>0)) {
                        time = TlsUtil.utilDate2String(date, "yyyy-MM", false);
                    } else if(peroid == 2 && priceArr.length()==0){
                        time = TlsUtil.utilDate2String(date, "yyyy", false);
                    }
                    if(!startMap.containsKey(time)) {
                        startMap.put(time, unit.value);
                    }
                    if(i == units.size()-1) {
                        startMap.put("end", unit.value);
                    }
                }
                String prev = null;
                units = new ArrayList<>();
                for(String time: startMap.keySet()) {
                    if(null == prev) {
                        prev = time;
                        continue;
                    }
                    double value = Double.parseDouble((String) startMap.get(time))-Double.parseDouble((String) startMap.get(prev));
                    HistoryDataUnit unit = new HistoryDataUnit();
                    unit.setTime(prev);
                    unit.setValue(String.valueOf(value));
                    units.add(unit);
                    prev = time;
                }
                if(priceArr.length() > 0) {
                    units = computePrice(units, peroid, priceArr);
                    List<HistoryDataUnit> unitList = new ArrayList<>();
                    if(0 == peroid) {
                        Date startTime = TlsUtil.string2utilDate((String) params.get("startTime"), "yyyy-MM-dd");
                        for(HistoryDataUnit unit : units) {
                            Date date = TlsUtil.string2utilDate(unit.getTime(), "yyyy-MM-dd");
                            if(date.after(startTime) || date.equals(startTime)) {
                                unitList.add(unit);
                            }
                        }
                        units = unitList;
                    }
                }
                int i=0;
                for(HistoryDataUnit unit : units) {
                    JSONObject row = new JSONObject();
                    row.put("id", ++i);
                    row.put("time", unit.getTime());
                    row.put("value", String.format("%.2f", Double.parseDouble(unit.getValue())));
                    list.add(row);
                    xDatas.add(unit.getTime());
                }
                JSONObject data = new JSONObject();
                data.put("ord", result.items.get(0).ord);
                data.put("name", result.items.get(0).name);
                data.put("list", list);
                datas.add(data);
                lists.add(units);
            }
        }
        List<Map<String, Object>> tDatas = new ArrayList<>();
        if(bTDatas == 1) {
            tDatas = buildTDatas(names, lists, xDatas, true);
        }
        jsonResultResponse(JSONResult.success("查询成功").add("datas", datas).add("tDatas", tDatas));
    }

    public void postEnergySum(WebOp op, String queryString) throws Exception {
        JSONResult pageResult = new JSONResult();
        Map<String, Object> params = resolveParams(queryString);
        String historyIds = (String) params.get("h");
        int peroid = Integer.parseInt((String) params.get("p"));
        String price = (String) params.get("price");
        if(StringUtils.isBlank(historyIds)) {
            jsonResponse(JSONResult.error("历史查询参数'historyId'配置错误"));
            return;
        }
        JSONArray priceArr = null;
        if(StringUtils.isNotBlank(price)) {
            priceArr = new JSONArray(price);
        }
        List<JSONObject> datas = new ArrayList<>();
        List<String> names = new ArrayList<>();
        String[] historyIdArray = historyIds.split("\\|\\|\\|");
        for(int i=0; i<historyIdArray.length; i++) {
            String[] history = historyIdArray[i].split("\\|\\|");
            HistoryDataItem historyDataItem = new HistoryDataItem();
            historyDataItem.name = history[0];
            historyDataItem.ord  = history[1].replace("history:", "");
            List<HistoryDataItem> items = new ArrayList<>();
            items.add(historyDataItem);
            HistoryDataMessage request = new HistoryDataMessage();
            request.startTime = (String) params.get("startTime");
            request.endTime = (String) params.get("endTime");
            String[] timeRange = EnergyUtil.getStatisticsTimeRange(request.startTime, request.endTime, peroid, 1, priceArr.length()>0);
            if(null == timeRange || timeRange.length < 2) {
                jsonResponse(JSONResult.error("历史查询时间范围错误"));
                return;
            }
            request.startTime = timeRange[0];
            request.endTime = timeRange[1];
            request.items = items;
            HistoryDataMessage result = HistoryManager.searchHistoryData(request);
            if(result != null && result.items != null && result.items.size()>0
                    && result.items.get(0).units != null
                    && result.items.get(0).units.size()>0) {
                List<HistoryDataUnit> units = result.items.get(0).units;
                List<JSONObject> list = new ArrayList<>();
                JSONObject row = new JSONObject();
                if(null == priceArr || priceArr.length() == 0) {
                    row.put("id", i+1);
                    row.put("name", history[0]);
                    String value = String.format("%.2f", Double.parseDouble(units.get(units.size()-1).value)-Double.parseDouble(units.get(0).value));
                    row.put("value", value);
                    list.add(row);
                    JSONObject data = new JSONObject();
                    data.put("ord", result.items.get(0).ord);
                    data.put("name", result.items.get(0).name);
                    data.put("list", list);
                    datas.add(data);
                } else {
                    Map<String, Object> startMap = new LinkedHashMap<>();
                    for (int j = 0; j < units.size(); j++) {
                        HistoryDataUnit unit = units.get(j);
                        Date date = TlsUtil.string2utilDate(unit.time);
                        String time = TlsUtil.utilDate2String(date, "yyyy-MM-dd", false);
                        if(peroid == 1 || (peroid == 2 && priceArr.length()>0)) {
                            time = TlsUtil.utilDate2String(date, "yyyy-MM", false);
                        } else if(peroid == 2 && priceArr.length()==0){
                            time = TlsUtil.utilDate2String(date, "yyyy", false);
                        }
                        if(!startMap.containsKey(time)) {
                            startMap.put(time, unit.value);
                        }
                        if(i == units.size()-1) {
                            startMap.put("end", unit.value);
                        }
                    }
                    String prev = null;
                    units = new ArrayList<>();
                    for(String time: startMap.keySet()) {
                        if(null == prev) {
                            prev = time;
                            continue;
                        }
                        double value = Double.parseDouble((String) startMap.get(time))-Double.parseDouble((String) startMap.get(prev));
                        HistoryDataUnit unit = new HistoryDataUnit();
                        unit.setTime(prev);
                        unit.setValue(String.valueOf(value));
                        units.add(unit);
                        prev = time;
                    }
                    units = computePrice(units, peroid, priceArr);
                    if(0 == peroid) {
                        List<HistoryDataUnit> unitList = new ArrayList<>();
                        Date startTime = TlsUtil.string2utilDate((String) params.get("startTime"), "yyyy-MM-dd");
                        for(HistoryDataUnit unit : units) {
                            Date date = TlsUtil.string2utilDate(unit.getTime(), "yyyy-MM-dd");
                            if(date.after(startTime) || date.equals(startTime)) {
                                unitList.add(unit);
                            }
                        }
                        units = unitList;
                    }
                    double value = 0;
                    for(HistoryDataUnit unit : units) {
                        value += Double.parseDouble(unit.getValue());
                    }
                    row.put("id", i+1);
                    row.put("name", history[0]);
                    row.put("value", String.format("%.2f", value));
                    list.add(row);
                    JSONObject data = new JSONObject();
                    data.put("ord", result.items.get(0).ord);
                    data.put("name", result.items.get(0).name);
                    data.put("list", list);
                    datas.add(data);
                }
            }
        }
        jsonResultResponse(JSONResult.success("查询成功").add("datas", datas));
    }

    public void postEnergySame(WebOp op, String queryString) throws Exception {
        JSONResult pageResult = new JSONResult();
        Map<String, Object> params = resolveParams(queryString);
        String historyId = (String) params.get("h");
        int peroid = Integer.parseInt((String) params.get("p"));
        String price = (String) params.get("price");
        if(StringUtils.isBlank(historyId)) {
            jsonResponse(JSONResult.error("历史查询参数'historyId'配置错误"));
            return;
        }
        JSONArray priceArr = null;
        if(StringUtils.isNotBlank(price)) {
            priceArr = new JSONArray(price);
        }
        List<JSONObject> datas = new ArrayList<>();
        List<String> names = new ArrayList<>();
        String[] history = historyId.split("\\|\\|");
        HistoryDataItem historyDataItem = new HistoryDataItem();
        historyDataItem.name = history[0];
        historyDataItem.ord  = history[1].replace("history:", "");
        Date startTime = TlsUtil.string2utilDate((String) params.get("startTime"), peroid == 0?"yyyy-MM-dd":(peroid == 1?"yyyy-MM":"yyyy"));
        Date endTime = TlsUtil.string2utilDate((String) params.get("endTime"), peroid == 0?"yyyy-MM-dd":(peroid == 1?"yyyy-MM":"yyyy"));
        Calendar calendar = Calendar.getInstance();
        for(int i=1; i>=0; i--) {
            List<HistoryDataItem> items = new ArrayList<>();
            items.add(historyDataItem);
            HistoryDataMessage request = new HistoryDataMessage();
            calendar.setTime(startTime);
            calendar.add(Calendar.YEAR, -1*i);
            request.startTime = TlsUtil.utilDate2String(calendar.getTime(), peroid == 0?"yyyy-MM-dd":(peroid == 1?"yyyy-MM":"yyyy"), false);
            Date startTimeN = calendar.getTime();
            calendar.setTime(endTime);
            calendar.add(Calendar.YEAR, -1*i);
            request.endTime = TlsUtil.utilDate2String(calendar.getTime(), peroid == 0?"yyyy-MM-dd":(peroid == 1?"yyyy-MM":"yyyy"), false);
            String nameSpan = request.startTime + " - " + request.endTime;
            String[] timeRange = EnergyUtil.getStatisticsTimeRange(request.startTime, request.endTime, peroid, 1, priceArr.length()>0);
            if(null == timeRange || timeRange.length < 2) {
                jsonResponse(JSONResult.error("历史查询时间范围错误"));
                return;
            }
            request.startTime = timeRange[0];
            request.endTime = timeRange[1];
            request.items = items;
            HistoryDataMessage result = HistoryManager.searchHistoryData(request);
            if(result != null) {
                List<JSONObject> list = new ArrayList<>();
                JSONObject row = new JSONObject();
                if(result.items == null || result.items.size() == 0 || result.items.get(0).units == null || result.items.get(0).units.size() == 0) {
                    row.put("id", i+1);
                    row.put("name", nameSpan);
                    row.put("value", "0.00");
                    list.add(row);
                    JSONObject data = new JSONObject();
                    data.put("ord", historyDataItem.ord);
                    data.put("name", nameSpan);
                    data.put("list", list);
                    datas.add(data);
                    continue;
                }
                List<HistoryDataUnit> units = result.items.get(0).units;
                if(null == priceArr || priceArr.length() == 0) {
                    row.put("id", i+1);
                    row.put("name", nameSpan);
                    String value = String.format("%.2f", Double.parseDouble(units.get(units.size()-1).value)-Double.parseDouble(units.get(0).value));
                    row.put("value", value);
                    list.add(row);
                    JSONObject data = new JSONObject();
                    data.put("ord", result.items.get(0).ord);
                    data.put("name", nameSpan);
                    data.put("list", list);
                    datas.add(data);
                } else {
                    Map<String, Object> startMap = new LinkedHashMap<>();
                    for (int j = 0; j < units.size(); j++) {
                        HistoryDataUnit unit = units.get(j);
                        Date date = TlsUtil.string2utilDate(unit.time);
                        String time = TlsUtil.utilDate2String(date, "yyyy-MM-dd", false);
                        if(peroid == 1 || (peroid == 2 && priceArr.length()>0)) {
                            time = TlsUtil.utilDate2String(date, "yyyy-MM", false);
                        } else if(peroid == 2 && priceArr.length()==0){
                            time = TlsUtil.utilDate2String(date, "yyyy", false);
                        }
                        if(!startMap.containsKey(time)) {
                            startMap.put(time, unit.value);
                        }
                        if(i == units.size()-1) {
                            startMap.put("end", unit.value);
                        }
                    }
                    String prev = null;
                    units = new ArrayList<>();
                    for(String time: startMap.keySet()) {
                        if(null == prev) {
                            prev = time;
                            continue;
                        }
                        double value = Double.parseDouble((String) startMap.get(time))-Double.parseDouble((String) startMap.get(prev));
                        HistoryDataUnit unit = new HistoryDataUnit();
                        unit.setTime(prev);
                        unit.setValue(String.valueOf(value));
                        units.add(unit);
                        prev = time;
                    }
                    units = computePrice(units, peroid, priceArr);
                    if(0 == peroid) {
                        List<HistoryDataUnit> unitList = new ArrayList<>();
                        for(HistoryDataUnit unit : units) {
                            Date date = TlsUtil.string2utilDate(unit.getTime(), "yyyy-MM-dd");
                            if(date.after(startTimeN) || date.equals(startTimeN)) {
                                unitList.add(unit);
                            }
                        }
                        units = unitList;
                    }
                    double value = 0;
                    for(HistoryDataUnit unit : units) {
                        value += Double.parseDouble(unit.getValue());
                    }
                    row.put("id", i+1);
                    row.put("name", nameSpan);
                    row.put("value", String.format("%.2f", value));
                    list.add(row);
                    JSONObject data = new JSONObject();
                    data.put("ord", result.items.get(0).ord);
                    data.put("name", nameSpan);
                    data.put("list", list);
                    datas.add(data);
                }
            } else {
                break;
            }
        }
        jsonResultResponse(JSONResult.success("查询成功").add("datas", datas));
    }

    public void postEnergyProportionTrend(WebOp op, String queryString) throws Exception {
        Map<String, Object> params = resolveParams(queryString);
        String historyIds = (String) params.get("h");
        int bTDatas = Integer.parseInt((String) params.get("t"));
        int peroid = Integer.parseInt((String) params.get("p"));
        String price = (String) params.get("price");
        if(StringUtils.isBlank(historyIds)) {
            jsonResponse(JSONResult.error("历史查询参数'historyId'配置错误"));
            return;
        }
        JSONArray priceArr = null;
        if(StringUtils.isNotBlank(price)) {
            priceArr = new JSONArray(price);
        }
        List<JSONObject> datas = new ArrayList<>();
        SortedSet<String> xDatas = new TreeSet<>();
        List<String> names = new ArrayList<>();
        List<List<HistoryDataUnit>> lists = new ArrayList<>();
        String[] historyIdArray = historyIds.split("\\|\\|\\|");
        for(String historyId : historyIdArray) {
            String[] history = historyId.split("\\|\\|");
            HistoryDataItem historyDataItem = new HistoryDataItem();
            historyDataItem.name = history[0];
            names.add(history[0]);
            historyDataItem.ord  = history[1].replace("history:", "");
            List<HistoryDataItem> items = new ArrayList<>();
            items.add(historyDataItem);
            HistoryDataMessage request = new HistoryDataMessage();
            request.startTime = (String) params.get("startTime");
            request.endTime = (String) params.get("endTime");
            String[] timeRange = EnergyUtil.getStatisticsTimeRange(request.startTime, request.endTime, peroid, 2, priceArr.length()>0);
            if(null == timeRange || timeRange.length < 2) {
                jsonResponse(JSONResult.error("历史查询时间范围错误"));
                return;
            }
            request.startTime = timeRange[0];
            request.endTime = timeRange[1];
            request.items = items;
            Map<String, Object> startMap = new LinkedHashMap<>();
            HistoryDataMessage result = HistoryManager.searchHistoryData(request);
            if(result != null && result.items != null && result.items.size()>0
                    && result.items.get(0).units != null
                    && result.items.get(0).units.size()>0) {
                List<HistoryDataUnit> units = result.items.get(0).units;
                for (int i = 0; i < units.size(); i++) {
                    HistoryDataUnit unit = units.get(i);
                    Date date = TlsUtil.string2utilDate(unit.time);
                    String time = TlsUtil.utilDate2String(date, "yyyy-MM-dd", false);
                    if(peroid == 1 || (peroid == 2 && priceArr.length()>0)) {
                        time = TlsUtil.utilDate2String(date, "yyyy-MM", false);
                    } else if(peroid == 2 && priceArr.length()==0){
                        time = TlsUtil.utilDate2String(date, "yyyy", false);
                    }
                    if(!startMap.containsKey(time)) {
                        startMap.put(time, unit.value);
                    }
                    if(i == units.size()-1) {
                        startMap.put("end", unit.value);
                    }
                }
                String prev = null;
                units = new ArrayList<>();
                for(String time: startMap.keySet()) {
                    if(null == prev) {
                        prev = time;
                        continue;
                    }
                    double value = Double.parseDouble((String) startMap.get(time))-Double.parseDouble((String) startMap.get(prev));
                    HistoryDataUnit unit = new HistoryDataUnit();
                    unit.setTime(prev);
                    unit.setValue(String.valueOf(value));
                    units.add(unit);
                    prev = time;
                }
                List<HistoryDataUnit> unitList = new ArrayList<>();
                if(priceArr.length() > 0) {
                    units = computePrice(units, peroid, priceArr);
                    if(0 == peroid) {
                        Date startTime = TlsUtil.string2utilDate((String) params.get("startTime"), "yyyy-MM-dd");
                        for(HistoryDataUnit unit : units) {
                            Date date = TlsUtil.string2utilDate(unit.getTime(), "yyyy-MM-dd");
                            if(date.after(startTime) || date.equals(startTime)) {
                                unitList.add(unit);
                            }
                        }
                        units = unitList;
                    }
                }
                unitList = new ArrayList<>();
                for(HistoryDataUnit unit : units) {
                    unit.setValue(String.format("%.2f", Double.parseDouble(unit.getValue())));
                    unitList.add(unit);
                    xDatas.add(unit.getTime());
                }
                lists.add(units);
            }
        }
        List<Map<String, Object>> tDatas = new ArrayList<>();
        if(bTDatas == 1) {
            tDatas = buildTDatas(names, lists, xDatas, false);
        }
        if(null != tDatas && tDatas.size() > 0) {
            Map<String, List<JSONObject>> listMap = new HashMap<>();
            for(String name:names) {
                listMap.put(name, new ArrayList<>());
            }
            for(Map<String, Object> item : tDatas) {
                for(String key:item.keySet()) {
                    if(names.contains(key)) {
                        JSONObject row = new JSONObject();
                        row.put("id", item.get("id"));
                        row.put("time",item.get("time"));
                        row.put("value", item.get(key));
                        listMap.get(key).add(row);
                    }
                }
            }
            for(String name:names) {
                JSONObject data = new JSONObject();
                data.put("ord", "");
                data.put("name", name);
                data.put("list", listMap.get(name));
                datas.add(data);
            }
        }
        jsonResultResponse(JSONResult.success("查询成功").add("datas", datas).add("tDatas", tDatas));
    }

    public void postEnergyHistoryAccum(WebOp op, String queryString) throws Exception {
        Map<String, Object> params = resolveParams(queryString);
        String historyId = (String) params.get("h");
        int peroid = Integer.parseInt((String) params.get("p"));
        if(StringUtils.isBlank(historyId) || (peroid != 0 && peroid != 1 && peroid != 2)) {
            jsonResponse(JSONResult.error("请求参数错误"));
            return;
        }
        HistoryDataItem historyDataItem = new HistoryDataItem();
        historyDataItem.ord  = historyId.replace("history:", "");
        List<HistoryDataItem> items = new ArrayList<>();
        items.add(historyDataItem);
        HistoryDataMessage request = new HistoryDataMessage();
        String format = peroid==0?"yyyy-MM-dd":(peroid==1?"yyyy-MM":"yyyy");
        String startTime = TlsUtil.utilDate2String(new Date(), format,true);
        String endTime = startTime;
        String[] timeRange = EnergyUtil.getStatisticsTimeRange(startTime, endTime, peroid, -1, false);
        if(null == timeRange || timeRange.length < 2) {
            jsonResponse(JSONResult.error("历史查询时间范围错误"));
            return;
        }
        LOGGER.info("postEnergyHistoryAccum timeRange: " + timeRange[0] + " = " + timeRange[1]);
        request.startTime = timeRange[1];
        request.endTime = timeRange[0];
        request.items = items;
        HistoryDataMessage result = HistoryManager.searchHistoryData(request);
        if(result != null && result.items != null && result.items.size()>0) {
            List<HistoryDataUnit> units = result.items.get(0).units;
            double value = 0;
            if(null != units && units.size() > 2) {
                value = Double.parseDouble(units.get(units.size()-1).value)-Double.parseDouble(units.get(0).value);
            }
            jsonResultResponse(JSONResult.success("查询成功").add("value", value));
            return;
        }
        jsonResponse(JSONResult.error("统计值查询"));
    }
}
